#include "stdafx.h"
#include "xml_tree.h"
using namespace ui;
using namespace std;

//void XmlTreeNode::OnClickItem()
//{
//	return;
//}
//
//void XmlTreeNode::OnDoubleClickItem()
//{
//	SetExpand(!IsExpand());
//	return;
//}

void XmlTreeNode::SetExpand(bool bExpand)
{
	if (GetChildNodeCount() > 0)
	{
		std::wstring bkimage = bExpand ? L"treenode_open_16x16.png" : L"treenode_close_16x16.png";
		FindSubControl(L"icon")->SetBkImage(bkimage);
	}
	
	__super::SetExpand(bExpand);
}


//----------------------------------------------------------------------------------------------
//-------------------------------------------XmlTree--------------------------------------------
//----------------------------------------------------------------------------------------------
XmlTree::XmlTree() : TreeView()
{
}


XmlTree::~XmlTree()
{
}

TreeNode *XmlTree::FindNodeByDataId(std::string id)
{
	TreeNode *root = m_pRootBox;
	TreeNode *nood = FindNodeByDataId(root, id);
	return nood;
}

TreeNode *XmlTree::FindNodeByDataId(TreeNode *node, std::string id)
{
	if (!node)
		return nullptr;
	if (node->GetUTF8DataID() == id)
		return node;
	TreeNode *findNode = nullptr;
	int size = node->GetChildNodeCount();
	for (int i = 0; i < size; i++)
	{
		TreeNode *childNode = node->GetChildNode(i);
		findNode = FindNodeByDataId(childNode, id);
		if (findNode)
			break;
	}
	return findNode;
}

bool XmlTree::InsertControl(Control* control, Box* parent)
{
	bool ret = false;
	std::string parentId = parent ? parent->GetUTF8DataID() : "";
	TreeNode *parentNode = FindNodeByDataId(parentId);
	if (!parentNode)
	{
		assert(!m_pRootBox);
		TreeNode *root = GetRootNode();

		TreeNode *node = new XmlTreeNode;
		ui::GlobalManager::FillBoxWithCache(node, L"examples/plant_tree/xml_tree_node.xml");
		std::wstring sClassName = control->GetControlClassName();
		std::wstring sName = control->GetName();
		std::wstring sContent;
		if (sName.empty())
			sContent = L"<" + sClassName + L" " + sContent + L">";
		else
			sContent = L"<" + sClassName + L"name=";
		static_cast<Label*>(node->FindSubControl(L"control"))->SetText(sContent);
		ret = root->AddChildNode(node);

		std::string id = control->GetUTF8DataID();
		assert(!id.empty());
		node->SetUTF8DataID(id);
		node->AttachSelect([this, id](ui::EventArgs* args){
			std::shared_ptr<StateEvent> event = std::make_shared<StateEvent>();
			event->from = this;
			event->ev = StateEvent_Selected;
			event->id = id;
			NotifyMaker(event);

			return true;
		});
		if (dynamic_cast<Box*>(control)){
			node->AttachDoubleClick([this, node](ui::EventArgs* args){
				node->SetExpand(!node->IsExpand());
				return true;
			});
		}
		else
			assert(0);

		m_pRootBox = node;
	}
	else
	{
		TreeNode *node = new XmlTreeNode;
		ui::GlobalManager::FillBoxWithCache(node, L"examples/plant_tree/xml_tree_node.xml");
		std::wstring sClassName = control->GetControlClassName();
		std::wstring sName = control->GetName();
		std::wstring sContent;
		if (sName.empty())
			sContent = sClassName;
		else
			sContent = sClassName + L" " + sName;
		static_cast<Label*>(node->FindSubControl(L"control"))->SetText(sContent);
		ret = parentNode->AddChildNode(node);
		std::string id = control->GetUTF8DataID();
		assert(!id.empty());
		node->SetUTF8DataID(id);
		node->AttachSelect([this, id](ui::EventArgs* args){
			std::shared_ptr<StateEvent> event = std::make_shared<StateEvent>();
			event->from = this;
			event->ev = StateEvent_Selected;
			event->id = id;
			NotifyMaker(event);
			return true;
		});
		node->AttachBubbledEvent(kEventMouseEnter, [this, id](ui::EventArgs* args) {
			std::shared_ptr<StateEvent> event = std::make_shared<StateEvent>();
			event->from = this;
			event->ev = StateEvent_MouseEnter;
			event->id = id;
			printf("NotifyMaker(event) StateEvent_MouseEnter\n");
			NotifyMaker(event);
			return false;
			});
		Box* box = dynamic_cast<Box*>(control);
		if (box){
			if (box->IsBoxControl())
				node->FindSubControl(L"icon")->SetBkImage(L"control.png");
		}
		else
		{
			node->FindSubControl(L"icon")->SetBkImage(L"control.png");
		}
	}
	return ret;
}

bool XmlTree::InsertBox(Box* box, Box* parent)
{
	if (!box)
		return false;
	bool ret = InsertControl(box, parent);
	if (!box->IsBoxControl())
	{
		int count = box->GetCount();
		for (int i = 0; i < count; i++)
		{
			Control* p = box->GetItemAt(i);
			Box* b = dynamic_cast<Box*>(p);
			if (b)
			{
				InsertBox(b, box);
			}
			else
			{
				InsertControl(p, box);
			}
		}
	}
	
	return ret;
}

bool XmlTree::ReBuiildTree(Box* root, Control* control)
{
	RemoveAllNode();
	return InsertBox(root, nullptr);
}

bool XmlTree::DoStateEvent(std::shared_ptr<StateEvent> event)
{
	if (event->ev == StateEvent_InsertControl || event->ev == StateEvent_InsertBox)
	{
		return InsertControl(event->p, event->parent);
	}
	else if (event->ev == StateEvent_ResetRoot)
	{
		return ReBuiildTree(event->parent, event->p);
	}
	return true;
}

